import VolumeControllers
import Downloaders
import time
import os
from Common import * 
from Globals import *
import Servers
import re
import sys
import urllib
import pluginloader

class MediaController():
	'''
	Dit is de hoofdfunctie, deze zal plugins inladen en de basis van de	mediacontroller opstarten (geluid, speler,...). Deze klasse zal vaak ook gebruikt worden door andere klasses om bepaalde functies te laten werken. Het heeft de functie van een facade.
	'''
	def __init__(self):
		#Sound
		self.volumeController = VolumeControllers.VolumeControllers()		#alsa default, idea: OSS4 support
		self.volumePoints = 5												#How much increase/decrease for volume
		#Downloader
		self.urlParser = Downloaders.Youtube()
		MPlayer.populate()
		self.MP = MPlayer()
		hook.shareVar(MP=self.MP)
		hook.shareVar(YT=self.urlParser)
		#Extra
		self.d = None
		# self.hook

#
#	Sound functions
#
	def volumeUp(self):
		'''Met deze functie kan het systeem-volume omhoog worden gezet met de vaste waarde	die in volumePoints is gedefinieert. Bij success zal hij de currentVolumelevel teruggeven, anders -1'''
		hook.runHooks('volumeUp_before', level=self.volumeController.currentVolumelevel())
		if(self.volumeController.volumeUp(self.volumePoints) >= 0):
			hook.runHooks('volumeUp_after', level=self.volumeController.currentVolumelevel())
			return self.volumeController.currentVolumelevel()
		else:
			return -1
	def volumeDown(self):
		'''
		Met deze functie kan het systeem-volume omlaag worden gezet met de vaste waarde die in volumePoints is gedefinieert. Bij success zal hij de currentVolumelevel teruggeven, anders -1 lala
		'''
		hook.runHooks('volumeDown_before', level=self.volumeController.currentVolumelevel())
		if(self.volumeController.volumeDown(self.volumePoints) >= 0):
			hook.runHooks('volumeDown_after', level=self.volumeController.currentVolumelevel())
			return self.volumeController.currentVolumelevel()
		else:
			return -1		
	def getSoundVolume(self):
		'''
		Met deze functie zal het huidige systeem-volume worden teruggegeven.
		'''
		hook.runHooks('getSoundVolume_before')
		return self.volumeController.currentVolumelevel()

	def muteVolume(self):
		'''
		Met deze functie zal het systeem-volume meteen worden gemute
		'''
		hook.runHooks('muteVolume_before')
		return self.volumeController.volumeOff()

	def unmuteVolume(self):
		'''
		Met deze functie zal het systeem-volume meteen worden unmute
		'''
		hook.runHooks('unmuteVolume_before')
		return self.volumeController.volumeOn()


	def playSong(self,song):
		'''
		Accepteer het argument song waar de titel van een liedje in zal staan. Zal met deze informatie het liedje opzoeken en beginnen af te spelen. Dit stopt wel niet	muziek die al opstaat maar zal ze in een lijst zetten. Indien je het meteen wilt afspelen wordt er aangeraden om eerst skipSong(1) aan te roepen.
		'''
		playlistFile = "/dev/shm/playlist.mc"
		p = open(playlistFile, "w")
		p.write(self.getYTlink(song))
		p.close()
		hook.runHooks('playSong_before', song=song)
		song = song.rstrip()
		self.MP.loadlist('/dev/shm/playlist.mc',1)
		hook.runHooks('playSong_after', song=song)

	def playSongFromFile(self,location):
		'''
		Werkt hetzelfde als playSong maar hier moet je een locatie meegeven, dit kan een url zijn of een locatie op het systeem zelf.
		'''
		hook.runHooks('playSongFromFile_before', location=location)
		self.MP.loadfile(location,1)
		hook.runHooks('playSongFromFile_after', location=location)

	def playPlaylist(self,location):
		'''
		Je kan je eigen playlists inladen via deze functie, een playlist is gewoon een bestand met een locatie-url naar het audio-bestand per lijn.
		'''
		hook.runHooks('playPlaylist_before', location=location)
		self.MP.loadlist(location,1)
		hook.runHooks('playPlaylist_after', location=location)		

	def stopPlaying(self):
		'''
		Dit stopt de mediacontroller met audio-bestanden af te spelen.
		'''
		hook.runHooks('stopPlaying_before')
		self.MP.stop()
		hook.runHooks('stopPlaying_after')

	def skipSong(self, amount):
		'''
		Indien je een playlist hebt ingeladen kan je naar volgende liedjes gaan en ook terugkeren met positieve waarde en negatieve waarden. 
		'''
		hook.runHooks('skipSong_before')
		self.MP.pt_step(amount)
		hook.runHooks('skipSong_after')

	def send(self, client,msg):
		'''
		deprecated
		'''
		try:
			if client != None:
				client.send(msg)
		except:
			pass

	def getYTlink(self,keywords):
		'''
		Zal de absolute link van een clipje op youtube teruggeven die gevonden werd met	de zoekterm (keywords)
		'''
		return self.urlParser.getDownloadLink(self.urlParser.getFirstResult(keywords))

	def getYTlinkfromYTid(self,id):
		'''
		Zelfde als getYTlink buiten dat je hier inplaats van keywords een youtube-ID meegeeft.
		'''
		return self.urlParser.getDownloadLink(id)	

	def playSongfromYT(self,link):
		'''
		deprecated, zelfde als playSongFromFile
		'''
		self.MP.loadfile(self.getYTlinkfromYTid(link),1)

	def addFolder(self,folder):	
		'''
		Met deze functie kan je een folder meegeven en de mediacontroller zal dan elk mp3/flv/mkv/mp4 bestand in een playlist zetten en afspelen! Uitkijken dat je niet folder "/" doet of je moet even geduld uitoefenen!
		'''
		hook.runHooks('addFolder_before', folder=folder)
		for root, subFolders, files in os.walk(folder):
			for file_name in files:
				#Let avbin check them all on files (very intensive CPU job) or use regex for fileformat. Until easier CPU job, regex it is
				if re.match("(.*)\.(mc|mp3|flv|mkv|mp4)",file_name):
					self.MP.loadfile("%s/%s" % (str(root), file_name),1)
		hook.runHooks('addFolder_after', folder=folder)

	def loadPlugins(self):
		'''
		Deze functie hoort normaal niet meer geroepen te worden door eindgebruikers/andere klasses maar zal de functies inladen en de functie run()	van die plugin oproepen.
		'''
		for i in pluginloader.getPlugins():
		    print("Loading plugin " + i["name"])
		    plugin = pluginloader.loadPlugin(i)
		    plugin.run()
try:
	main = MediaController()
	hook.shareVar(main=main) # Make sure this is BEFORE plugins are loaded - many rely on Main being shared
	main.loadPlugins()
	server = Servers.SetupServer(3333,main)
except KeyboardInterrupt:
	sys.exit("KeyboardInterrupt")